/**
 * 内存管理工具 - IntelliMark适配版
 * 提供AI对话和内容记忆功能
 */

import { BaseTool, ToolResult, MemoryAction, MemoryOptions } from "../../types/tools";
import { v4 as uuidv4 } from 'uuid';

// 内存条目接口
export interface MemoryEntry {
  id: string;
  type: 'conversation' | 'document' | 'context' | 'user_preference';
  content: string;
  metadata: Record<string, any>;
  timestamp: Date;
  importance: number; // 0-1
  tags: string[];
  relatedIds: string[];
}

// 搜索结果
export interface MemorySearchResult {
  entry: MemoryEntry;
  relevanceScore: number;
  matchType: 'exact' | 'partial' | 'semantic';
}

// 内存管理配置
export interface MemoryManagementConfig {
  maxEntries: number;
  maxAge: number; // 天数
  importanceThreshold: number;
  enablePersistence: boolean;
  storagePath?: string;
}

export class MemoryManagementTool extends BaseTool {
  private config: MemoryManagementConfig;
  private memory: Map<string, MemoryEntry> = new Map();
  private embeddings: Map<string, number[]> = new Map(); // 简单的向量存储

  constructor(config: Partial<MemoryManagementConfig> = {}) {
    super();

    this.name = 'memory-management';
    this.description = 'IntelliMark内存管理工具，负责管理对话历史、文档上下文和用户偏好等记忆信息';
    this.category = 'memoryManagement';
    this.enabled = true;
    this.requiresAuth = false;

    this.config = {
      maxEntries: 1000,
      maxAge: 30, // 30天
      importanceThreshold: 0.3,
      enablePersistence: true,
      storagePath: './memory',
      ...config,
    };

    this.parameters = [
      {
        name: 'action',
        type: 'string' as const,
        description: '内存操作类型',
        required: true,
        validation: {
          enum: ['store', 'retrieve', 'search', 'update', 'delete', 'clear'],
        },
      },
      {
        name: 'data',
        type: 'object' as const,
        description: '操作数据',
        required: false,
      },
      {
        name: 'query',
        type: 'string' as const,
        description: '搜索查询',
        required: false,
      },
      {
        name: 'options',
        type: 'object' as const,
        description: '操作选项',
        required: false,
      },
    ];
  }

  async execute(input: any): Promise<ToolResult> {
    const startTime = Date.now();
    const requestId = uuidv4();

    try {
      // 验证输入参数
      const validatedInput = this.validateInput(input);

      // 执行内存操作
      const result = await this.performMemoryAction(validatedInput);

      const executionTime = Date.now() - startTime;

      return {
        success: true,
        data: result,
        metadata: {
          executionTime,
          action: validatedInput.action,
          requestId,
          totalEntries: this.memory.size,
        },
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error);

      return {
        success: false,
        error: errorMessage,
        metadata: {
          executionTime: Date.now() - startTime,
          requestId,
        },
      };
    }
  }

  private validateInput(input: any): { action: MemoryAction; data?: any; query?: string; options?: MemoryOptions } {
    if (!input.action) {
      throw new Error('action参数是必需的');
    }

    const validActions: MemoryAction[] = ['store', 'retrieve', 'search', 'update', 'delete', 'clear'];
    if (!validActions.includes(input.action)) {
      throw new Error(`无效的action: ${input.action}`);
    }

    const validated: any = {
      action: input.action,
    };

    // 根据操作类型验证必需参数
    switch (input.action) {
      case 'store':
        if (!input.data) {
          throw new Error('store操作需要data参数');
        }
        validated.data = input.data;
        break;

      case 'retrieve':
      case 'delete':
        if (!input.data?.id && !input.query) {
          throw new Error('retrieve/delete操作需要data.id或query参数');
        }
        validated.data = input.data;
        validated.query = input.query;
        break;

      case 'search':
        if (!input.query) {
          throw new Error('search操作需要query参数');
        }
        validated.query = input.query;
        break;

      case 'update':
        if (!input.data?.id) {
          throw new Error('update操作需要data.id参数');
        }
        validated.data = input.data;
        break;
    }

    if (input.options) {
      validated.options = {
        memoryType: input.options.memoryType || 'conversation',
        namespace: input.options.namespace || 'default',
        limit: input.options.limit || 10,
        threshold: input.options.threshold || 0.5,
        ...input.options,
      };
    }

    return validated;
  }

  private async performMemoryAction(params: { action: MemoryAction; data?: any; query?: string; options?: MemoryOptions }): Promise<any> {
    switch (params.action) {
      case 'store':
        return this.storeMemory(params.data, params.options);

      case 'retrieve':
        return this.retrieveMemory(params.data?.id, params.query, params.options);

      case 'search':
        return this.searchMemory(params.query!, params.options);

      case 'update':
        return this.updateMemory(params.data, params.options);

      case 'delete':
        return this.deleteMemory(params.data?.id, params.query, params.options);

      case 'clear':
        return this.clearMemory(params.options);

      default:
        throw new Error(`不支持的操作: ${params.action}`);
    }
  }

  private storeMemory(data: any, options?: MemoryOptions): MemoryEntry {
    const entry: MemoryEntry = {
      id: data.id || uuidv4(),
      type: data.type || 'conversation',
      content: data.content || '',
      metadata: data.metadata || {},
      timestamp: new Date(),
      importance: data.importance || 0.5,
      tags: data.tags || [],
      relatedIds: data.relatedIds || [],
    };

    // 添加特定于命名空间的信息
    if (options?.namespace) {
      entry.metadata.namespace = options.namespace;
    }

    // 存储到内存
    this.memory.set(entry.id, entry);

    // 生成简单的嵌入向量（基于关键词）
    const embedding = this.generateEmbedding(entry.content);
    this.embeddings.set(entry.id, embedding);

    // 清理过期和超限的条目
    this.cleanupMemory();

    return entry;
  }

  private retrieveMemory(id?: string, query?: string, options?: MemoryOptions): MemoryEntry | MemoryEntry[] {
    if (id) {
      const entry = this.memory.get(id);
      return entry || null;
    }

    if (query) {
      const results = this.searchMemory(query, options);
      return results.map(r => r.entry);
    }

    // 返回最近的条目
    return this.getRecentEntries(options?.limit || 10, options);
  }

  private searchMemory(query: string, options?: MemoryOptions): MemorySearchResult[] {
    const queryEmbedding = this.generateEmbedding(query);
    const threshold = options?.threshold || 0.5;
    const limit = options?.limit || 10;

    const results: MemorySearchResult[] = [];

    this.memory.forEach((entry, id) => {
      // 检查命名空间过滤
      if (options?.namespace && entry.metadata.namespace !== options.namespace) {
        return;
      }

      // 检查内存类型过滤
      if (options?.memoryType && entry.type !== options.memoryType) {
        return;
      }

      // 计算相似度
      const entryEmbedding = this.embeddings.get(id);
      if (!entryEmbedding) return;

      const similarity = this.calculateSimilarity(queryEmbedding, entryEmbedding);

      if (similarity >= threshold) {
        results.push({
          entry,
          relevanceScore: similarity,
          matchType: similarity > 0.8 ? 'exact' : similarity > 0.5 ? 'partial' : 'semantic',
        });
      }
    });

    // 按相关性排序
    results.sort((a, b) => b.relevanceScore - a.relevanceScore);

    return results.slice(0, limit);
  }

  private updateMemory(data: any, options?: MemoryOptions): MemoryEntry | null {
    const existing = this.memory.get(data.id);
    if (!existing) {
      return null;
    }

    const updated: MemoryEntry = {
      ...existing,
      ...data,
      timestamp: new Date(), // 更新时间戳
    };

    this.memory.set(data.id, updated);

    // 更新嵌入向量
    if (data.content) {
      const embedding = this.generateEmbedding(data.content);
      this.embeddings.set(data.id, embedding);
    }

    return updated;
  }

  private deleteMemory(id?: string, query?: string, options?: MemoryOptions): boolean {
    if (id) {
      const deleted = this.memory.delete(id);
      if (deleted) {
        this.embeddings.delete(id);
      }
      return deleted;
    }

    if (query) {
      const results = this.searchMemory(query, options);
      let deletedCount = 0;
      results.forEach(result => {
        this.memory.delete(result.entry.id);
        this.embeddings.delete(result.entry.id);
        deletedCount++;
      });
      return deletedCount > 0;
    }

    return false;
  }

  private clearMemory(options?: MemoryOptions): { deletedCount: number } {
    let deletedCount = 0;

    if (options?.namespace) {
      // 清除特定命名空间
      const toDelete: string[] = [];
      this.memory.forEach((entry, id) => {
        if (entry.metadata.namespace === options.namespace) {
          toDelete.push(id);
        }
      });

      toDelete.forEach(id => {
        this.memory.delete(id);
        this.embeddings.delete(id);
        deletedCount++;
      });
    } else if (options?.memoryType) {
      // 清除特定类型
      const toDelete: string[] = [];
      this.memory.forEach((entry, id) => {
        if (entry.type === options.memoryType) {
          toDelete.push(id);
        }
      });

      toDelete.forEach(id => {
        this.memory.delete(id);
        this.embeddings.delete(id);
        deletedCount++;
      });
    } else {
      // 清除所有
      deletedCount = this.memory.size;
      this.memory.clear();
      this.embeddings.clear();
    }

    return { deletedCount };
  }

  private generateEmbedding(text: string): number[] {
    // 简单的嵌入向量生成（基于词汇频率）
    // 在实际应用中，应该使用专业的嵌入模型
    const words = text.toLowerCase().split(/\s+/);
    const vector = new Array(100).fill(0); // 100维向量

    words.forEach((word, index) => {
      const hash = this.simpleHash(word);
      const position = hash % 100;
      vector[position] += 1 / (index + 1); // 位置权重
    });

    // 归一化
    const magnitude = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
    return magnitude > 0 ? vector.map(val => val / magnitude) : vector;
  }

  private simpleHash(str: string): number {
    let hash = 0;
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash; // 转换为32位整数
    }
    return Math.abs(hash);
  }

  private calculateSimilarity(vec1: number[], vec2: number[]): number {
    // 计算余弦相似度
    const dotProduct = vec1.reduce((sum, val, i) => sum + val * vec2[i], 0);
    const magnitude1 = Math.sqrt(vec1.reduce((sum, val) => sum + val * val, 0));
    const magnitude2 = Math.sqrt(vec2.reduce((sum, val) => sum + val * val, 0));

    if (magnitude1 === 0 || magnitude2 === 0) return 0;
    return dotProduct / (magnitude1 * magnitude2);
  }

  private cleanupMemory(): void {
    const now = Date.now();
    const maxAge = this.config.maxAge * 24 * 60 * 60 * 1000; // 转换为毫秒
    const toDelete: string[] = [];

    this.memory.forEach((entry, id) => {
      const age = now - entry.timestamp.getTime();

      // 删除过期条目
      if (age > maxAge) {
        toDelete.push(id);
        return;
      }

      // 删除低重要性条目（如果内存已满）
      if (this.memory.size > this.config.maxEntries && entry.importance < this.config.importanceThreshold) {
        toDelete.push(id);
      }
    });

    // 如果仍然超出限制，删除最旧的条目
    if (this.memory.size - toDelete.length > this.config.maxEntries) {
      const entries = Array.from(this.memory.entries())
        .sort((a, b) => a[1].timestamp.getTime() - b[1].timestamp.getTime());

      const excess = this.memory.size - toDelete.length - this.config.maxEntries;
      for (let i = 0; i < excess; i++) {
        toDelete.push(entries[i][0]);
      }
    }

    // 执行删除
    toDelete.forEach(id => {
      this.memory.delete(id);
      this.embeddings.delete(id);
    });

    if (toDelete.length > 0) {
      console.log(`Cleaned up ${toDelete.length} memory entries`);
    }
  }

  private getRecentEntries(limit: number, options?: MemoryOptions): MemoryEntry[] {
    const entries = Array.from(this.memory.values())
      .filter(entry => {
        if (options?.namespace && entry.metadata.namespace !== options.namespace) {
          return false;
        }
        if (options?.memoryType && entry.type !== options.memoryType) {
          return false;
        }
        return true;
      })
      .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
      .slice(0, limit);

    return entries;
  }

  // 公共方法
  public getMemoryStats(): {
    totalEntries: number;
    entriesByType: Record<string, number>;
    oldestEntry?: Date;
    newestEntry?: Date;
    averageImportance: number;
  } {
    if (this.memory.size === 0) {
      return {
        totalEntries: 0,
        entriesByType: {},
        averageImportance: 0,
      };
    }

    const entriesByType: Record<string, number> = {};
    let totalImportance = 0;
    let oldestTimestamp = Date.now();
    let newestTimestamp = 0;

    this.memory.forEach(entry => {
      entriesByType[entry.type] = (entriesByType[entry.type] || 0) + 1;
      totalImportance += entry.importance;

      const timestamp = entry.timestamp.getTime();
      oldestTimestamp = Math.min(oldestTimestamp, timestamp);
      newestTimestamp = Math.max(newestTimestamp, timestamp);
    });

    return {
      totalEntries: this.memory.size,
      entriesByType,
      oldestEntry: new Date(oldestTimestamp),
      newestEntry: new Date(newestTimestamp),
      averageImportance: totalImportance / this.memory.size,
    };
  }

  public updateConfig(newConfig: Partial<MemoryManagementConfig>): void {
    this.config = { ...this.config, ...newConfig };
    this.cleanupMemory();
  }

  // 便捷方法
  public storeConversation(content: string, metadata?: Record<string, any>): MemoryEntry {
    return this.storeMemory({
      type: 'conversation',
      content,
      metadata,
      importance: 0.6,
      tags: ['conversation'],
    });
  }

  public storeDocument(content: string, metadata?: Record<string, any>): MemoryEntry {
    return this.storeMemory({
      type: 'document',
      content,
      metadata,
      importance: 0.8,
      tags: ['document'],
    });
  }

  public storeContext(content: string, metadata?: Record<string, any>): MemoryEntry {
    return this.storeMemory({
      type: 'context',
      content,
      metadata,
      importance: 0.7,
      tags: ['context'],
    });
  }

  public storeUserPreference(preference: string, value: any): MemoryEntry {
    return this.storeMemory({
      type: 'user_preference',
      content: `${preference}: ${JSON.stringify(value)}`,
      metadata: { preference, value },
      importance: 0.9,
      tags: ['preference', preference],
    });
  }
}

// 导出便捷函数
export const createMemoryManagementTool = (config?: Partial<MemoryManagementConfig>): MemoryManagementTool => {
  return new MemoryManagementTool(config);
};

// 默认实例
export const defaultMemoryManagementTool = new MemoryManagementTool();